/*
 * Copyright 2011 Thomas Golden
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.j2bugzilla.rpc;


import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.text.ParseException;

import com.j2bugzilla.base.BugzillaMethod;
import com.j2bugzilla.base.HistoryElement;
import com.j2bugzilla.base.HistoryElement.Change;


/**
 * Allows users to retrieve a specific bug for which the ID is already known
 * 
 * @author Tom
 *
 */
public class GetBugHistory implements BugzillaMethod {

	/**
	 * The method name for this {@link BugzillaMethod}
	 */
	private static final String METHOD_NAME = "Bug.history";
	
	private Map<Object, Object> hash = new HashMap<Object, Object>();
	private Map<Object, Object> params = new HashMap<Object, Object>();
	
	/**
	 * Creates a new {@link GetBugHistory} object to retrieve the {@code Bug} specified
	 * by the ID parameter
	 * @param id An {@code int} representing the ID of an existing bug in the
	 * installation connected to
	 */
	public GetBugHistory(int id) {
		params.put("ids", id);
	}
	
	/**
	 * Creates a new {@link GetBugHistory} object to retrieve the {@code Bug} specified by the
	 * unique alias.
	 * @param alias A {@code String} representing a bug alias in the Bugzilla installation.
	 */
	public GetBugHistory(String alias) {
		params.put("ids", alias);
	}
	
	
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setResultMap(Map<Object, Object> hash) {
		this.hash = hash;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Map<Object, Object> getParameterMap() {
		return Collections.unmodifiableMap(params);
	}
	
	/**
	 * Gets bug history.
	 * @throws ParseException If the parsing of the date failed.
	 */
	
	@SuppressWarnings("unchecked")
	public List<HistoryElement> getBugHistory() throws ParseException {
		List<HistoryElement> result = null;
		if(hash.containsKey("bugs")) {
			
			Object[] bugs = (Object[])hash.get("bugs");
			if(bugs.length == 0) { 
				return result; //early return if map is empty
			}
			
			result = new ArrayList<HistoryElement>();
			
			//Loop over the bugs for which we get history. It should only have one bug in it.
			//Either way, this will return the history for the last bug ID in the list.
			for(Object o : bugs) {
				
				Map<String, Object> histMap = (HashMap<String, Object>)o;
				Object[] histItems = (Object[])histMap.get("history");
				
				//Loop over the history items. Each one becomes a HistoryElemen.t
				for(Object hi : histItems)
				{
					
					Map<String, Object> hiMap = (HashMap<String, Object>)hi;
					String who = (String)hiMap.get("who");
					Date when = (Date)hiMap.get("when");
					Object[] changesObj = (Object[])hiMap.get("changes");
					Set<Change> chset = new HashSet<Change>(); //Will be passed to the HistoryElement constructor.
					
					for (Object chob : changesObj)
					{
						Map<String, String> chmap = (Map<String, String>)chob;
						
						Change ch = new Change(chmap.get("field_name"), chmap.get("added"), chmap.get("removed"));
						chset.add(ch);
					}

					HistoryElement newHistElem = new HistoryElement(who, when, chset);
					result.add(newHistElem);
				}
			}
		}
		return result;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getMethodName() {
		return METHOD_NAME;
	}
}
